<h2>Why is this an issue?</h2>
<p>In order to produce a formatted string, both <code>string.Create</code> and either <code>FormattableString.Invariant</code> or
<code>FormattableString.CurrentCulture</code> can be used. However, <code>string.Create</code> rents array buffers from
<code>ArrayPool&lt;char&gt;</code> making it more performant, as well as preventing unnecessary allocations and future stress on the Garbage
Collector.</p>
<p>This applies to .NET versions after .NET 6, when these <code>string.Create</code> overloads were introduced.</p>
<h3>What is the potential impact?</h3>
<p>We measured a significant improvement both in execution time and memory allocation. For more details see the <code>Benchmarks</code> section from
the <code>More info</code> tab.</p>
<h2>How to fix it</h2>
<p>Replace calls to <code>FormattableString.CurrentCulture</code> or <code>FormattableString.Invariant</code> with calls to
<code>string.Create(CultureInfo.CurrentCulture, …​)</code> or <code>string.Create(CultureInfo.InvariantCulture, …​)</code> respectively.</p>
<h3>Code examples</h3>
<h4>Noncompliant code example</h4>
<pre data-diff-id="1" data-diff-type="noncompliant">
string Interpolate(string value) =&gt;
    FormattableString.Invariant($"Value: {value}");
</pre>
<pre data-diff-id="2" data-diff-type="noncompliant">
string Interpolate(string value) =&gt;
    FormattableString.CurrentCulture($"Value: {value}");
</pre>
<h4>Compliant solution</h4>
<pre data-diff-id="1" data-diff-type="compliant">
string Interpolate(string value) =&gt;
    string.Create(CultureInfo.InvariantCulture, $"Value: {value}");
</pre>
<pre data-diff-id="2" data-diff-type="compliant">
string Interpolate(string value) =&gt;
    string.Create(CultureInfo.CurrentCulture, $"Value: {value}");
</pre>
<h2>Resources</h2>
<h3>Documentation</h3>
<ul>
  <li> <a href="https://learn.microsoft.com/en-us/dotnet/api/system.string.create?view=net-7.0">string.Create</a> </li>
  <li> <a href="https://learn.microsoft.com/en-us/dotnet/api/system.formattablestring.invariant">FormattableString.Invariant</a> </li>
  <li> <a href="https://learn.microsoft.com/en-us/dotnet/api/system.formattablestring.currentculture">FormattableString.CurrentCulture</a> </li>
</ul>
<h3>Articles &amp; blog posts</h3>
<ul>
  <li> <a
  href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated#compilation-of-interpolated-strings">Compilation of
  interpolated strings</a> </li>
</ul>
<h3>Benchmarks</h3>
<p>The results were generated by running the following snippet with <a href="https://github.com/dotnet/BenchmarkDotNet">BenchmarkDotNet</a>:</p>
<table>
  <colgroup>
    <col style="width: 20%;">
    <col style="width: 20%;">
    <col style="width: 20%;">
    <col style="width: 20%;">
    <col style="width: 20%;">
  </colgroup>
  <thead>
    <tr>
      <th>Method</th>
      <th>Runtime</th>
      <th>Mean</th>
      <th>Standard Deviation</th>
      <th>Allocated</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><p>StringCreate</p></td>
      <td><p>.NET 7.0</p></td>
      <td><p>152.5 ms</p></td>
      <td><p>3.09 ms</p></td>
      <td><p>83.92 MB</p></td>
    </tr>
    <tr>
      <td><p>FormattableString</p></td>
      <td><p>.NET 7.0</p></td>
      <td><p>191.8 ms</p></td>
      <td><p>6.92 ms</p></td>
      <td><p>198.36 MB</p></td>
    </tr>
  </tbody>
</table>
<h4>Glossary</h4>
<ul>
  <li> <a href="https://en.wikipedia.org/wiki/Arithmetic_mean">Mean</a> </li>
  <li> <a href="https://en.wikipedia.org/wiki/Standard_deviation">Standard Deviation</a> </li>
  <li> <a href="https://en.wikipedia.org/wiki/Memory_management">Allocated</a> </li>
</ul>
<p>The results were generated by running the following snippet with <a href="https://github.com/dotnet/BenchmarkDotNet">BenchmarkDotNet</a>:</p>
<pre>
int Value = 42;
DateTime Now = DateTime.UtcNow;

[Params(1_000_000)]
public int N;

[Benchmark]
public void StringCreate()
{
    for (int i = 0; i &lt; N; i++)
    {
        _ = string.Create(CultureInfo.InvariantCulture, $"{Now}: Value is {Value}");
    }
}

[Benchmark]
public void FormattableStringInvariant()
{
    for (int i = 0; i &lt; N; i++)
    {
        _ = FormattableString.Invariant($"{Now}: Value is {Value}");
    }
}
</pre>
<p>Hardware configuration:</p>
<pre>
BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2728/22H2/2022Update)
11th Gen Intel Core i7-11850H 2.50GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK=7.0.203
  [Host]   : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
  .NET 7.0 : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
</pre>

